package com.sxwl.auth.netty;

import com.alibaba.fastjson.JSON;
import com.sxwl.auth.service.ChatInfoService;
import com.sxwl.auth.utils.SpringUtil;
import com.sxwl.pojo.ChatMessage;
import com.sxwl.pojo.ChatRecord;
import com.sxwl.pojo.Message;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author reading
 * @Description TODO
 * @Date 2020/4/12 21:19
 */
@Slf4j
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    // 用来保存所有的客户端连接
    // private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:MM");
    // 当Channel中有新的事件消息会自动调用
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        // 当接收到数据后会自动调用
        // 获取客户端发送过来的文本消息
        String text = msg.text();
        System.out.println("接收到消息数据为：" + text);
        Message message = JSON.parseObject(text, Message.class);
        // 通过SpringUtil工具类获取Spring上下文容器
        ChatInfoService onlineUserService = SpringUtil.getBean(ChatInfoService.class);
        switch (message.getType()) {
            // 处理客户端连接的消息
            case 0:
                // 建立用户与通道的关联
                flushMessage(message);//刷新用户列表
                String userid = message.getChatRecord().getUserid();
                UserChannelMap.put(userid, ctx.channel());
                // 刷新消息
                break;
            // 处理客户端发送好友消息
            case 1:
           //      将聊天消息保存到数据库
                try {
                    ChatRecord chatRecord = message.getChatRecord();
                    chatRecord.setCreatetime(new Date());
                    chatRecord.setHasRead(0);//0未读消息
                    onlineUserService.saveRecord(message.getChatRecord());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                /**
                 * 保存聊天消息
                 */
                //如果已经创建了聊天消息就不再保存了
                String userid1 = message.getChatRecord().getUserid();
                List<ChatMessage> chatMessageList = onlineUserService.isSave(userid1,message.getChatRecord().getFriendid());
                if(CollectionUtils.isEmpty(chatMessageList)){
                    ChatMessage chatMessage=new ChatMessage();
                    chatMessage.setFriendid(message.getChatRecord().getFriendid());
                    chatMessage.setUserid(message.getChatRecord().getUserid());
                    onlineUserService.saveChatMessage(chatMessage);
                }
                // 如果发送消息好友在线，可以直接将消息发送给好友
                Channel channel = UserChannelMap.get(message.getChatRecord().getFriendid());
                if(channel != null) {
                    channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message)));
                }
                break;
            // 把消息设为已读
            case 2:
                log.info("设置消息为已读");
                if(StringUtils.isEmpty(message.getChatRecord().getUserid())||StringUtils.isEmpty(message.getChatRecord().getFriendid())){
                    return;
                }
                onlineUserService.setMessageHasRead(Integer.valueOf(message.getChatRecord().getUserid()),Integer.valueOf(message.getChatRecord().getFriendid()));
                break;
            case 3:
                // 接收心跳消息
                System.out.println("接收到心跳消息:" + JSON.toJSONString(message));
                break;
            case 4:

                break;
        }
    }
    // 当有新的客户端连接服务器之后，会自动调用这个方法
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // 将新的通道加入到clients
//        clients.add(ctx.channel());
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        UserChannelMap.removeByChannelId(ctx.channel().id().asLongText());
        Message message=new Message();
        message.setType(0);
        flushMessage(message);
        ctx.channel().close();
    }
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        UserChannelMap.removeByChannelId(ctx.channel().id().asLongText());
    }
    public void flushMessage(Message ms){
        ConcurrentHashMap<String,Channel> channelMap = UserChannelMap.getChannelMap();
        log.info("当前用户数量-{}",channelMap.size());
        channelMap.entrySet().forEach(item->{
            Channel channel = item.getValue();
            channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(ms)));
        });
    }
}
